package api

import (
	"Wechat/Tools"
	"Wechat/domain"
	"Wechat/service"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/thedevsaddam/gojsonq"
	"io/ioutil"
	"net/http"
)

// 新建一个service的变量,用于调用函数
var userinfoservice service.UserInfoService

// 用户注册接口
/*func UserRegister(c *gin.Context) {
	fmt.Println("This UserRegister Api")
	//	读取数据 : json
	var userMap = make(map[string]interface{})
	c.BindJSON(&userMap)
	userID := userMap["id"].(string)
	userPassword := userMap["password"].(string)
	userIdentity := userMap["identity"].(string)
	userUnionID := userMap["unionid"].(string)
	// 值得注意的是,golang中的map是随机顺序,和你的插入顺序没有关系
	var res = make(map[string]interface{})
	var isValid bool = true
	if userID == "" {
		res["ERROR"] = "ID is invalid!"
		isValid = false
	}
	if userPassword == "" {
		res["ERROR"] = "password is invalid!"
		isValid = false
	}
	if userIdentity == "" {
		res["ERROR"] = "identity is invalid!"
		isValid = false
	}
	if userUnionID == "" {
		res["ERROR"] = "unionid is invalid!"
		isValid = false
	}
	// 如果是有效的,则正常输出
	if isValid {
		if userinfoservice.AddUser(userID, userPassword, userIdentity, userUnionID) {
			res["msg"] = http.StatusText(http.StatusOK)
		} else {
			res["msg"] = "Fail"
			res["ERROR"] = "Add userinfo Fail"
		}
	} else {
		res["msg"] = "Fail"
	}
	c.JSON(http.StatusOK, res)
	return
}*/

// UserRegister 用户注册接口
func UserRegister(c *gin.Context) {
	//	 读取页面数据
	user := domain.User{}
	err := c.BindJSON(&user)
	Tools.CherrError(err, "Get user message ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get user register message Fail！",
		})
		return
	}
	fmt.Println(user)
	//	判断读取到的数据是否有效
	var isValid bool = true
	var resErrorStr string = ""
	if user.UserID == "" {
		resErrorStr = "ID is invalid!	"
		isValid = false
	}
	if user.UserPassword == "" {
		resErrorStr = "password is invalid!    "
		isValid = false
	}
	if user.UserIdentity == "" {
		resErrorStr = "identity is invalid!    "
		isValid = false
	}
	if user.UserPassword == "" {
		resErrorStr = "unionid is invalid!    "
		isValid = false
	}
	//	如果无效则返回错误信息
	if !isValid {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": resErrorStr,
		})
		return
	}
	//	如果有效则添加
	if userinfoservice.AddUser(user) {
		c.JSON(http.StatusOK, gin.H{
			"msg": http.StatusText(http.StatusOK),
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Register user Fail!",
		})
	}
}

// UserLogin 用户登录接口
func UserLogin(c *gin.Context) {
	fmt.Println("This UserLogin Api")
	//	读取数据 : json
	var userMap = make(map[string]interface{})
	c.BindJSON(&userMap)
	userID := userMap["id"].(string)
	userPassword := userMap["password"].(string)
	userUnionID := userMap["unionid"].(string)
	// 确定验证是否成功,并且输出对应信息
	if isMatch, msgStr := userinfoservice.VerifyUser(userID, userPassword, userUnionID); isMatch {
		c.JSON(http.StatusOK, gin.H{
			"msg": http.StatusText(http.StatusOK),
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": msgStr,
		})
	}
	return
}

// 用户修改个人信息
/*func UserModifyMessage(c *gin.Context) {
	fmt.Println("This is UserModifyMessage")
	//	获取页面信息: form-data
	userName := c.DefaultPostForm("name", "")
	userNickName := c.DefaultPostForm("nickname", "")
	userGrade := c.DefaultPostForm("grade", "")
	userSchool := c.DefaultPostForm("school", "")
	userUnionID := c.DefaultPostForm("unionid", "")
	// 获取头像文件并且存储下来
	headFile, err := c.FormFile("headpicpath")
	Tools.CherrError(err, "Get head picture ERROR!")
	// 图片存储路径
	filepath := Tools.PicturePath + "User/" + headFile.Filename
	err = c.SaveUploadedFile(headFile, filepath)
	Tools.CherrError(err, "Save head picture ERROR!")
	// 图片存入数据库的路径
	headPicPath := "http://" + Tools.IPAddr + Tools.Port + "/Picture/User/" + headFile.Filename
	Tools.CherrError(err, "Save head picture ERROR!")
	//	判断是否可以插入，并返回相应信息
	if isOk, resStr := userinfoservice.AddUserMessage(userName, userNickName, headPicPath, userGrade, userSchool, userUnionID); isOk {
		c.JSON(http.StatusOK, gin.H{
			"msg": resStr,
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": resStr,
		})
	}
}*/

// UserModifyMessage 用户修改信息（重写）
func UserModifyMessage(c *gin.Context) {
	fmt.Println("This is UserModifyMessage")
	//	获取页面信息
	var user = domain.User{}
	err := c.BindJSON(&user)
	Tools.CherrError(err, "Get user message ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get user message Fail!",
		})
		return
	}
	//	存储用户信息
	if isOk, resStr := userinfoservice.AddUserMessage(user); isOk {
		c.JSON(http.StatusOK, gin.H{
			"msg": http.StatusText(http.StatusOK),
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": resStr,
		})
	}
}

// UserAddHeadPicture 上传用户头像
func UserAddHeadPicture(c *gin.Context) {
	//	获取头像文件
	headFile, err := c.FormFile("headpicpath")
	Tools.CherrError(err, "Get head picture ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get head picture Fail!",
		})
		return
	}
	//  图片存储
	filepath := Tools.PicturePath + "User/" + headFile.Filename
	err = c.SaveUploadedFile(headFile, filepath)
	Tools.CherrError(err, "Save head picture ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Sava head picture Fail!",
		})
		return
	}
	//	图片存入数据库路径
	headPicPath := "http://" + Tools.IPAddr + Tools.Port + "/Pictures/User/" + headFile.Filename
	c.JSON(http.StatusOK, gin.H{
		"msg":      http.StatusText(http.StatusOK),
		"filepath": headPicPath,
	})
}

// UserGetMessage 返回用户信息
func UserGetMessage(c *gin.Context) {
	fmt.Println("This is Get user message!")
	// 获取unionid，通过其返回用户信息 :json
	var userMap = make(map[string]interface{})
	c.BindJSON(&userMap)
	unionID := userMap["unionid"].(string)
	var res = make(map[string]interface{})
	isOk, res := userinfoservice.GetUserMessage(unionID)
	if isOk {
		res["msg"] = http.StatusText(http.StatusOK)
		c.JSON(http.StatusOK, res)
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "unionid is invalid!",
		})
	}
}

// UserModifyPassword 修改密码
func UserModifyPassword(c *gin.Context) {
	//	读取数据
	var userMap = make(map[string]interface{})
	c.BindJSON(&userMap)
	unionID := userMap["unionid"].(string)
	userID := userMap["userid"].(string)
	oldPassword := userMap["oldpassword"].(string)
	newPassword := userMap["newpassword"].(string)
	// 如果新密码为空，返回错误
	if newPassword == "" {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "newpassword is not null",
		})
		return
	}
	//	判断是否修改成功并且返回对应信息
	if isOk, res := userinfoservice.ModifyUserPassword(unionID, userID, oldPassword, newPassword); isOk {
		c.JSON(http.StatusOK, gin.H{
			"msg": http.StatusText(http.StatusOK),
		})
	} else {
		res["msg"] = "Fail"
		c.JSON(http.StatusOK, res)
	}
}

// EnrollActivity 用户报名活动
func EnrollActivity(c *gin.Context) {
	//	 获取页面信息
	user := domain.User{}
	err := c.BindJSON(&user)
	Tools.CherrError(err, "Get user unionid ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get user unionid Fail!",
		})
		return
	}
	//	 存储用户用户信息
	if isOk, resStr := userinfoservice.AddUserActivity(user.UnionID, user.ActivityID); isOk {
		c.JSON(http.StatusOK, gin.H{
			"msg": http.StatusText(http.StatusOK),
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": resStr,
		})
	}
}

// GetUserActivity 查询用户是否报名活动，返回活动列表或者空
func GetUserActivity(c *gin.Context) {
	// 获取页面信息
	var userMap = make(map[string]interface{})
	err := c.BindJSON(&userMap)
	Tools.CherrError(err, "Get user unionID ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get user unionid Fail!",
		})
		return
	}
	unionID := userMap["unionid"].(string)
	//	 获取指定用户的活动信息
	if isOk, resStrs := userinfoservice.GetUserActivityList(unionID); isOk {
		c.JSON(http.StatusOK, gin.H{
			"msg":  http.StatusText(http.StatusOK),
			"data": resStrs,
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get user activity Fail!",
		})
	}
}

// 参考链接：https://blog.csdn.net/qq_50737715/article/details/123972451?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1.pc_relevant_default&spm=1001.2101.3001.4242.2&utm_relevant_index=3

// 这里存放你的appid、apsecret、以及获取网址
const (
	code2sessionURL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
	appID           = "wxf58558547a7b352a"
	appSecret       = "c2ca1a3ee37256c970a0d6c4f4e475fc"
)

// WechatLogin 微信登录接口
func WechatLogin(c *gin.Context) {
	//获取code：前端传过来
	//code := c.PostForm("code")
	openIDMap := make(map[string]interface{})
	err := c.BindJSON(&openIDMap)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get openID Fail!",
		})
		return
	}
	code := openIDMap["code"].(string)
	//调用auth.code2Session接口获取openid
	//这里应该是格式化信息
	url := fmt.Sprintf(code2sessionURL, appID, appSecret, code)
	// 获取这个网址中的内容
	resp, err := http.Get(url)
	Tools.CherrError(err, "Get openID ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get openID Fail!",
		})
		return
	}
	// 函数退出时，关闭网页请求Get
	defer resp.Body.Close()
	// ioutil包：https://zhuanlan.zhihu.com/p/76231663
	// ReadAll()读取所有数据
	body, err := ioutil.ReadAll(resp.Body)
	Tools.CherrError(err, "Get openID ERROR!")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":   "Fail",
			"ERROR": "Get openID Fail!",
		})
		return
	}
	// body是一个[]byte切片
	// 先将读取到的数据body转化为string，然后在其中寻找openid的数据，找到后转化为json
	// 将得到的数据中的openId转化为string
	json := gojsonq.New().FromString(string(body)).Find("openid")
	session := gojsonq.New().FromString(string(body)).Find("session_key")
	sessionid := session.(string)
	openID := json.(string)
	fmt.Println("my openid is: ", openID)
	fmt.Println("my session is: ", sessionid)
	// 成功之后返回openID
	c.JSON(http.StatusOK, gin.H{
		"msg":    http.StatusText(http.StatusOK),
		"openid": openID,
	})
}
